package com.nageoffer.jobtrain.projects.annotation;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nageoffer.jobtrain.common.web.exception.ClientException;
import com.nageoffer.jobtrain.projects.common.biz.user.UserContext;
import com.nageoffer.jobtrain.projects.common.enums.UserStatusEnums;
import com.nageoffer.jobtrain.projects.dao.entity.UserDO;
import com.nageoffer.jobtrain.projects.dao.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 用户状态拉黑切面类控制器
 * author：唐晨
 */
@Aspect
@Slf4j
@RequiredArgsConstructor
@Component
public class NoUserBlockingActionAspect {
    private final UserMapper userMapper;

    @Around("@annotation(com.nageoffer.jobtrain.projects.annotation.NoUserBlockingAction)")
    public Object noUserBlockingAction(ProceedingJoinPoint joinPoint) throws Throwable {
        NoUserBlockingAction noUserBlockingAction = getNoUserBlockingAction(joinPoint);
        // 获取注解参数
        String message = noUserBlockingAction.message();
        String phoneNumber = UserContext.getUsername();
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery(UserDO.class)
                .eq(UserDO::getPhoneNumber, phoneNumber)
                .eq(UserDO::getDelFlag, 0);
        UserDO userDO = userMapper.selectOne(queryWrapper);
        if (ObjectUtil.equal(userDO.getStatus(), UserStatusEnums.BLOCKING.getType())) {
            // 此时用户状态已经拉黑，直接抛异常
            throw new ClientException(message);
        }
        // 执行目标方法
        return joinPoint.proceed();
    }

    /**
     * @return 返回防止用户拉黑操作自定义注解
     */
    private static NoUserBlockingAction getNoUserBlockingAction(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method targetMethod = joinPoint.getTarget().getClass()
                .getDeclaredMethod(methodSignature.getName(), methodSignature.getMethod().getParameterTypes());
        return targetMethod.getAnnotation(NoUserBlockingAction.class);
    }
}
